import spider_config
import time
from threading import RLock, get_ident
from common.logger import logger


class SpiderLock:
    def __init__(self, platform_id, account, interval_limit) -> None:
        super().__init__()

        self.platform_id = platform_id
        self.account = account
        self.interval_limit = interval_limit
        self.lock = RLock()
        self.last_time = 0
        self.owner = None

    def acquire(self):
        self.lock.acquire()
        if self.owner != get_ident():
            now = int(time.time() * 1000)
            wait_time = self.interval_limit - (now - self.last_time)
            if wait_time > 0:
                # logger.debug(f"阻塞{wait_time}毫秒")
                time.sleep(wait_time / 1000)
            self.last_time = int(time.time() * 1000)
            self.owner = get_ident()
        return self

    def release(self):
        self.lock.release()
        self.owner = None

    def locked(self):
        l = self.lock.acquire(False)
        if l:
            self.lock.release()
        return not l

    def __enter__(self):
        return self.acquire()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.release()


class LockManager:
    _instance = None

    def instance():
        if LockManager._instance is None:
            LockManager._instance = LockManager()
        return LockManager._instance

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self) -> None:
        super().__init__()
        self.__platform_interval_limit = {
            spider_config.su_park_id: 0,
            spider_config.etcp_park_id: 1000,
            spider_config.jie_park_id: 5000,
            spider_config.yima_park_id: 3000,
            spider_config.aiboke_park_id: 1000,
            spider_config.ymiot_park_id: 4000,
            spider_config.yun_park_id: 0,
            spider_config.ydt_park_id: 1000,
            spider_config.epark_park_id: 1000,
            spider_config.airun_park_id: 3000,
        }

        self.__account_lock = {}

    def __build_spider_lock(self, platform_id, account):
        return SpiderLock(
            platform_id, account, self.__platform_interval_limit[platform_id]
        )

    def get(self, platform_id, account):
        if account not in self.__account_lock:
            self.__account_lock[account] = self.__build_spider_lock(
                platform_id, account
            )

        return self.__account_lock[account]

    def locked(self, platform_id, account):
        if account not in self.__account_lock:
            return False
        return self.__account_lock[account].locked()
